Paul Tomblin updates CoPilot code..
authorrobertl <robertl>
Mon, 27 Nov 2006 01:00:12 +0000 (01:00 +0000)
committerrobertl <robertl>
Mon, 27 Nov 2006 01:00:12 +0000 (01:00 +0000)
copilot.c
defs.h
util.c
xmldoc/formats/copilot.xml

index b1b1c903b2b6b3ece9f6892ca1d926ba767cdf10..75412523a73f5963c2ae879f50d4109be538b180 100644 (file)
--- a/copilot.c
+++ b/copilot.c
 #include "coldsync/pdb.h"
 #include "grtcirc.h"
 
-#define MYNAME         "CoPilot Waypoint"
-#define MYTYPE                 0x77617970      /* wayp */
-#define MYCREATOR      0x47584255              /* GXBU */
+#define MYNAME                 "CoPilot Waypoint"
+#define wayp_TYPE              0x77617970      /* wayp */
+#define swpu_TYPE              0x73777075      /* swpu */
+#define GXPU_CREATOR   0x47584255              /* GXBU */
+#define AP_P_CREATOR   0x41502d50              /* AP-P */
 
 
-struct record {
+struct record0 {
+       pdb_double      latitude;       /* PDB double format, */
+       pdb_double      longitude;      /* similarly, neg = east */
+       pdb_double      magvar;         /* magnetic variation in degrees, neg = east */
+       udword          elevation;      /* feet */
+};
+
+struct record1 {
+       pdb_double      latitude;       /* PDB double format, */
+       pdb_double      longitude;      /* similarly, neg = east */
+       pdb_double      magvar;         /* magnetic variation in degrees, neg = east */
+       pdb_double      elevation;      /* feet */
+};
+
+struct record3 {
        pdb_double      latitude;       /* PDB double format, */
        pdb_double      longitude;      /* similarly, neg = east */
        pdb_double      magvar;         /* magnetic variation in degrees, neg = east */
        pdb_double      elevation;      /* feet */
-       char            flags;
+       char            flags;          /* flags */
+};
+
+struct record4 {
+       pdb_double      latitude;       /* PDB double format, */
+       pdb_double      longitude;      /* similarly, neg = east */
+       pdb_float       magvar;         /* magnetic variation in degrees, neg = east */
+       pdb_float       elevation;      /* feet */
 };
 
 static FILE *file_in;
@@ -69,10 +92,124 @@ wr_deinit(void)
        fclose(file_out);
 }
 
+static waypoint*
+read_version0(ubyte* data)
+{
+  char *vdata;
+  waypoint *wpt_tmp;
+  struct record0* rec = (struct record0*)data;
+
+  wpt_tmp = waypt_new();
+
+  wpt_tmp->longitude =
+       DEG(-pdb_read_double(&rec->longitude));
+  wpt_tmp->latitude =
+       DEG(pdb_read_double(&rec->latitude));
+  wpt_tmp->altitude = FEET_TO_METERS(be_read32(&rec->elevation));
+
+  vdata = (char *) data + sizeof(*rec);
+
+  wpt_tmp->shortname = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->description = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->notes = NULL;
+
+  return wpt_tmp;
+}
+
+static waypoint*
+read_version1(ubyte* data)
+{
+  char *vdata;
+  waypoint *wpt_tmp;
+  struct record1* rec = (struct record1*)data;
+
+  wpt_tmp = waypt_new();
+
+  wpt_tmp->longitude =
+       DEG(-pdb_read_double(&rec->longitude));
+  wpt_tmp->latitude =
+       DEG(pdb_read_double(&rec->latitude));
+  wpt_tmp->altitude =
+       FEET_TO_METERS(pdb_read_double(&rec->elevation));
+
+  vdata = (char *) data + sizeof(*rec);
+
+  wpt_tmp->shortname = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->description = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->notes = xstrdup(vdata);
+
+  return wpt_tmp;
+}
+
+static waypoint*
+read_version3(ubyte* data)
+{
+  char *vdata;
+  waypoint *wpt_tmp;
+  struct record3* rec = (struct record3*)data;
+
+  wpt_tmp = waypt_new();
+
+  wpt_tmp->longitude =
+       DEG(-pdb_read_double(&rec->longitude));
+  wpt_tmp->latitude =
+       DEG(pdb_read_double(&rec->latitude));
+  wpt_tmp->altitude =
+       FEET_TO_METERS(pdb_read_double(&rec->elevation));
+
+  vdata = (char *) data + sizeof(*rec);
+
+  wpt_tmp->shortname = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->description = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->notes = xstrdup(vdata);
+
+  return wpt_tmp;
+}
+
+static waypoint*
+read_version4(ubyte* data)
+{
+  char *vdata;
+  waypoint *wpt_tmp;
+  struct record4* rec = (struct record4*)data;
+
+  wpt_tmp = waypt_new();
+
+  wpt_tmp->longitude =
+       DEG(-pdb_read_double(&rec->longitude));
+  wpt_tmp->latitude =
+       DEG(pdb_read_double(&rec->latitude));
+  wpt_tmp->altitude =
+       FEET_TO_METERS(pdb_read_float(&rec->elevation));
+
+  vdata = (char *) data + sizeof(*rec);
+
+  wpt_tmp->shortname = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->description = xstrdup(vdata);
+  vdata = vdata + strlen(vdata) + 1;
+
+  wpt_tmp->notes = xstrdup(vdata);
+
+  return wpt_tmp;
+}
+
 static void
 data_read(void)
 {
-       struct record *rec;
        struct pdb *pdb;
        struct pdb_record *pdb_rec;
 
@@ -80,45 +217,46 @@ data_read(void)
                fatal(MYNAME ": pdb_Read failed\n");
        }
 
-       if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) {
+       if ((pdb->creator != GXPU_CREATOR && pdb->creator != AP_P_CREATOR) ||
+               (pdb->type != wayp_TYPE && pdb->type != swpu_TYPE)) {
                fatal(MYNAME ": Not a CoPilot file.\n");
        }
+       if (pdb->version > 4) {
+         fatal(MYNAME ": %d is not a known version.\n", pdb->version);
+       }
+
 
        for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
                waypoint *wpt_tmp;
-               char *vdata;
-
-               wpt_tmp = waypt_new();
-
-               rec = (struct record *) pdb_rec->data;
-               wpt_tmp->longitude =
-                 DEG(-pdb_read_double(&rec->longitude));
-               wpt_tmp->latitude =
-                 DEG(pdb_read_double(&rec->latitude));
-               wpt_tmp->altitude =
-                 pdb_read_double(&rec->elevation) * .3048;
-
-               vdata = (char *) pdb_rec->data + sizeof(*rec);
-
-               wpt_tmp->shortname = xstrdup(vdata);
-               vdata = vdata + strlen(vdata) + 1;
-
-               wpt_tmp->description = xstrdup(vdata);
-               vdata = vdata + strlen(vdata) + 1;
-               
-               wpt_tmp->notes = xstrdup(vdata);
 
+               switch (pdb->version)
+               {
+               case 0:
+                 wpt_tmp = read_version0(pdb_rec->data);
+                 break;
+               case 1:
+               case 2:
+                 wpt_tmp = read_version1(pdb_rec->data);
+                 break;
+               case 3:
+                 wpt_tmp = read_version3(pdb_rec->data);
+                 break;
+               case 4:
+                 wpt_tmp = read_version4(pdb_rec->data);
+                 break;
+               default:
+                 fatal(MYNAME ": Unknown version %d.\n", pdb->version);
+               }
                waypt_add(wpt_tmp);
 
        } 
        free_pdb(pdb);
 }
 
-
 static void
 copilot_writewpt(const waypoint *wpt)
 {
-       struct record *rec;
+       struct record4 *rec;
        static int ct = 0;
        char *vdata;
 
@@ -126,9 +264,9 @@ copilot_writewpt(const waypoint *wpt)
 
        pdb_write_double(&rec->latitude, RAD(wpt->latitude));
        pdb_write_double(&rec->longitude, RAD(-wpt->longitude));
-       pdb_write_double(&rec->elevation,
-               wpt->altitude / .3048);
-       pdb_write_double(&rec->magvar, 0);
+       pdb_write_float(&rec->magvar, 0);
+       pdb_write_float(&rec->elevation,
+               METERS_TO_FEET(wpt->altitude));
 
        vdata = (char *)rec + sizeof(*rec);
        if ( wpt->shortname ) {
@@ -180,9 +318,9 @@ data_write(void)
        opdb->name[PDB_DBNAMELEN-1] = 0;
        opdb->attributes = PDB_ATTR_BACKUP;
        opdb->ctime = opdb->mtime = current_time() + 2082844800U;
-       opdb->type = MYTYPE;
-       opdb->creator = MYCREATOR; 
-       opdb->version = 0;
+       opdb->type = wayp_TYPE;
+       opdb->creator = GXPU_CREATOR; 
+       opdb->version = 4;
 
        waypt_disp_all(copilot_writewpt);
        
diff --git a/defs.h b/defs.h
index daa85fef4c7325b9ea373363ea48145ba0da25a7..ce53d5f21cb443dbc22934c66e5782c52f64bf0a 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -785,6 +785,10 @@ typedef struct {
        unsigned char data[8];
 } pdb_double;
 
+typedef struct {
+       unsigned char data[4];
+} pdb_float;
+
 /*
  * Protypes for Endianness helpers.
  */
@@ -798,8 +802,10 @@ void be_write16(void *pp, const unsigned i);
 void be_write32(void *pp, const unsigned i);
 void le_write16(void *pp, const unsigned i);
 void le_write32(void *pp, const unsigned i);
+float pdb_read_float(void *p);
 double pdb_read_double(void *p);
 void pdb_write_double(void *pp, double d);
+void pdb_write_float(void *pp, float d);
 
 double le_read_double(void *p);
 double be_read_double(void *p);
diff --git a/util.c b/util.c
index 2ff419df2244036b2a8af6b2f6afc2f3d7fc2f09..9259e5ea639c9a963429645b251c7247237413c3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -890,6 +890,29 @@ endian_read_double(void* ptr, int read_le)
   return ret;
 }
 
+float
+endian_read_float(void* ptr, int read_le)
+{
+  float ret;
+  char r[4];
+  void *p;
+  int i;
+  
+  if ( i_am_little_endian == read_le ) {
+         p = ptr;
+  }
+  else {
+         for (i = 0; i < 4; i++)
+         {
+               r[i] = ((char*)ptr)[3-i];
+         }
+         p = r;
+  }
+  
+  memcpy(&ret, p, 4);
+  return ret;
+}
+
 void
 endian_write_double(void* ptr, double d, int write_le)
 {
@@ -908,9 +931,30 @@ endian_write_double(void* ptr, double d, int write_le)
   }
 }
 
+void
+endian_write_float(void* ptr, float f, int write_le)
+{
+  char *r = (char *)(void *)&f;
+  int i;
+  char *optr = ptr;
+
+  if ( i_am_little_endian == write_le ) {
+         memcpy( ptr, &f, 4);
+  }
+  else {
+         for (i = 0; i < 4; i++)
+         {
+               *optr++ = r[3-i];
+         }
+  }
+}
+
 double
 pdb_read_double( void *ptr ) {return endian_read_double(ptr, 0);}
 
+float
+pdb_read_float( void *ptr ) {return endian_read_float(ptr, 0);}
+
 double 
 le_read_double( void *ptr ) {return endian_read_double(ptr,1);}
 
@@ -920,6 +964,9 @@ be_read_double( void *ptr ) {return endian_read_double(ptr,0);}
 void
 pdb_write_double( void *ptr, double d ) {endian_write_double(ptr,d,0);}
 
+void
+pdb_write_float( void *ptr, float f ) {endian_write_float(ptr,f,0);}
+
 void
 le_write_double( void *ptr, double d ) {endian_write_double(ptr,d,1);}
 
index 4837f16271a649b624668a5a96aafbd4d66b697d..6eb5272def8f6c74a3b74df3fbb9a0ff2424bf07 100644 (file)
@@ -5,6 +5,9 @@
 Planner for Palm/OS"</ulink> databases into other formats.  You probably should
 not use this to write CoPilot databases, although the code is there,
 because GPSBabel doesn't convert magnetic declination values.</para>
+<para>This version now reads all CoPilot file versions up to 4, but only
+writes version 4 files.  If you have a need for a version flag, please let
+me know.</para>  
       <para> Questions, bug reports, etc, to ptomblin at
 xcski.com</para>
       <para>